﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Common;
using Wicture.EPC.Service.V1.Models;
using Wicture.EPC.Service.V1.Repository;
using Wicture.EPC.Common.Biz;
using System.Text;
using Wicture.EPC.Service.V1.Filters;
using Wicture.DbRESTFul;

namespace Wicture.EPC.Service.V1.QueryInterceptors.Interceptors
{
    public class ToyotaQueryInterceptor : BaseQueryInterceptor
    {
        private readonly string[] brandCodes = new string[] { "toyota", "lexus" };
        public override string[] BrandCodes => brandCodes;
        protected override List<Query_MainGroupResult> GetMainGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_MainGroupResult>(CSIs.Query_Main_Group_For_Not_Have_Model, param);
        }

        protected override IEnumerable<Query_SubGroupResult> GetSubGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_For_Toyota, param);
        }

        protected override List<Query_PartsResult> GetParts(DbRESTFulRepository repository, JObject param)
        {
            List<Query_PartsResult> partList = repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_For_Toyota, param);
            HandleSupersessionValid(repository, partList);
            partList = GroupParts(partList);
            return partList;
        }

        void HandleSupersessionValid(DbRESTFulRepository repository, List<Query_PartsResult> partList)
        {
            if (partList != null && partList.Any())
            {
                var list = partList.Where(e => !string.IsNullOrEmpty(e.replacedPartCodes));
                if (list != null && list.Any())
                {
                    var partCodes = list.Select(e => e.partCode);
                    IEnumerable<Query_SupersessionResult> partSupersessions = repository.Invoke<Query_SupersessionResult>(CSIs.Query_Supersessions_For_Toyota, new { partCodes = partCodes });

                    foreach (var item in partList)
                    {
                        if (!string.IsNullOrEmpty(item.replacedPartCodes))
                        {
                            string replacedPartCodes = string.Empty;

                            var supersessionTmpList = partSupersessions.Where(e => e.partCode1 == item.partCode);
                            if (supersessionTmpList != null && supersessionTmpList.Any())
                            {
                                foreach (var tmp in supersessionTmpList)
                                {
                                    if (string.IsNullOrEmpty(tmp.supersessionTime))
                                    {
                                        replacedPartCodes += tmp.partCode2 + ",";
                                    }
                                    else
                                    {
                                        if (tmp.supersessionTime.Length >= 6)
                                        {
                                            int time = 0;
                                            int.TryParse(tmp.supersessionTime.Substring(0, 6), out time);
                                            if (DateOperator.CompareOriginalDate(item.startTime, item.endTime, time, time))
                                            {
                                                replacedPartCodes += tmp.partCode2 + ",";
                                            }
                                        }
                                    }
                                }
                            }

                            item.replacedPartCodes = replacedPartCodes.Trim(',');
                        }
                    }
                }
            }
        }

        private List<Query_PartsResult> GroupParts(List<Query_PartsResult> partList)
        {
            List<Query_PartsResult> result = new List<Query_PartsResult>();
            if (partList != null && partList.Any())
            {
                var groupPartlist = from a in partList
                                    orderby a.id
                                    group a by new { imageSN = a.imageSN, partCode = a.partCode, startTime = a.startTime, endTime = a.endTime } into g
                                    select g;
                foreach (var item in groupPartlist)
                {
                    if (item.Count() == 1)
                    {
                        result.Add(item.FirstOrDefault());
                    }
                    else
                    {
                        Query_PartsResult tmp = null;
                        item.ForEach(a =>
                        {
                            //第一条
                            if (tmp == null)
                            {
                                tmp = (Query_PartsResult)a.Clone();
                                if (!string.IsNullOrEmpty(a.code))
                                {
                                    //拼接code为1开头的
                                    if (a.code.StartsWith("1"))
                                    {
                                        tmp.description = a.description;
                                    }
                                    //拼接其他
                                    else
                                    {
                                        tmp.otherDescription = a.description;
                                    }
                                }
                            }
                            else
                            {
                                if (a.type.CompareTo(tmp.type) < 0)
                                {
                                    result.Add(tmp);
                                    tmp = (Query_PartsResult)a.Clone();
                                    if (!string.IsNullOrEmpty(a.code))
                                    {
                                        //拼接code为1开头的
                                        if (a.code.StartsWith("1"))
                                        {
                                            tmp.description = a.description;
                                        }
                                        //拼接其他
                                        else
                                        {
                                            tmp.otherDescription = a.description;
                                        }
                                    }
                                }
                                else if (a.type.CompareTo(tmp.type) > 0)
                                {
                                    if (!string.IsNullOrEmpty(a.code))
                                    {
                                        //拼接code为1开头的
                                        if (a.code.StartsWith("1"))
                                        {
                                            tmp.description += a.description;
                                        }
                                        //拼接其他
                                        else
                                        {
                                            tmp.otherDescription += a.description;
                                        }
                                    }
                                }
                                //==
                                else
                                {
                                    if (a.type.Equals("1"))
                                    {
                                        result.Add(tmp);
                                        tmp = (Query_PartsResult)a.Clone();
                                    }
                                    else
                                    {
                                        if (a.code.CompareTo(tmp.code) > 0)
                                        {
                                            //拼接code为1开头的
                                            if (a.code.StartsWith("1"))
                                            {
                                                tmp.description += a.description;
                                            }
                                            //拼接其他
                                            else
                                            {
                                                tmp.otherDescription += a.description;
                                            }
                                        }
                                        else
                                        {
                                            result.Add(tmp);
                                            tmp = (Query_PartsResult)a.Clone();
                                            //拼接code为1开头的
                                            if (a.code.StartsWith("1"))
                                            {
                                                tmp.description += a.description;
                                            }
                                            //拼接其他
                                            else
                                            {
                                                tmp.otherDescription += a.description;
                                            }
                                        }
                                    }
                                }
                            }
                        });
                        if (tmp != null)
                        {
                            result.Add(tmp);
                        }
                    }
                }
            }
            return result;
        }

        private List<PartCatalogResult> GroupParts2(List<PartCatalogResult> partList)
        {
            List<PartCatalogResult> result = new List<PartCatalogResult>();
            if (partList != null && partList.Any())
            {
                var groupPartlist = from a in partList
                                    orderby a.id
                                    group a by new { a.subGroupId, a.imageSN, a.partCode, a.startTime, a.endTime } into g
                                    select g;
                foreach (var item in groupPartlist)
                {
                    if (item.Count() == 1)
                    {
                        result.Add(item.FirstOrDefault());
                    }
                    else
                    {
                        PartCatalogResult tmp = null;
                        item.ForEach(a =>
                        {
                            //第一条
                            if (tmp == null)
                            {
                                tmp = (PartCatalogResult)a.Clone();
                                if (!string.IsNullOrEmpty(a.code))
                                {
                                    //拼接code为1开头的
                                    if (a.code.StartsWith("1"))
                                    {
                                        tmp.description = a.description;
                                    }
                                    //拼接其他
                                    else
                                    {
                                        tmp.otherDescription = a.description;
                                    }
                                }
                            }
                            else
                            {
                                if (a.type.CompareTo(tmp.type) < 0)
                                {
                                    result.Add(tmp);
                                    tmp = (PartCatalogResult)a.Clone();
                                    if (!string.IsNullOrEmpty(a.code))
                                    {
                                        //拼接code为1开头的
                                        if (a.code.StartsWith("1"))
                                        {
                                            tmp.description = a.description;
                                        }
                                        //拼接其他
                                        else
                                        {
                                            tmp.otherDescription = a.description;
                                        }
                                    }
                                }
                                else if (a.type.CompareTo(tmp.type) > 0)
                                {
                                    if (!string.IsNullOrEmpty(a.code))
                                    {
                                        //拼接code为1开头的
                                        if (a.code.StartsWith("1"))
                                        {
                                            tmp.description += a.description;
                                        }
                                        //拼接其他
                                        else
                                        {
                                            tmp.otherDescription += a.description;
                                        }
                                    }
                                }
                                //==
                                else
                                {
                                    if (a.type.Equals("1"))
                                    {
                                        result.Add(tmp);
                                        tmp = (PartCatalogResult)a.Clone();
                                    }
                                    else
                                    {
                                        if (a.code.CompareTo(tmp.code) > 0)
                                        {
                                            //拼接code为1开头的
                                            if (a.code.StartsWith("1"))
                                            {
                                                tmp.description += a.description;
                                            }
                                            //拼接其他
                                            else
                                            {
                                                tmp.otherDescription += a.description;
                                            }
                                        }
                                        else
                                        {
                                            result.Add(tmp);
                                            tmp = (PartCatalogResult)a.Clone();
                                            //拼接code为1开头的
                                            if (a.code.StartsWith("1"))
                                            {
                                                tmp.description += a.description;
                                            }
                                            //拼接其他
                                            else
                                            {
                                                tmp.otherDescription += a.description;
                                            }
                                        }
                                    }
                                }
                            }
                        });
                        if (tmp != null)
                        {
                            result.Add(tmp);
                        }
                    }
                }
            }
            return result;
        }
        protected override List<Query_PartsResult> BuildPartResults(List<Query_PartsResult> list)
        {
            List<Query_PartsResult> res = new List<Query_PartsResult>();
            if (list != null && list.Any())
            {
                //特殊处理,超过1w取3千
                if (list != null && list.Count() > 3000)
                {
                    var groupedList = list.GroupBy(e => e.imageSN);
                    foreach (var item in groupedList)
                    {
                        res.AddRange(item.Where(e => e.belongToVin).Take(100));
                    }
                }
                else
                {
                    res = list;
                }

                res = res.OrderBy(e => e.imageSN.Length).ThenBy(e => e.imageSN).ThenBy(e => e.partCode).ToList();
                foreach (var item in res)
                {
                    if (string.IsNullOrEmpty(item.notes))
                    {
                        string startTime = item.startTime?.ToString();
                        string endTime = item.endTime?.ToString();

                        if (startTime == "999999")
                        {
                            startTime = "";
                        }
                        if (endTime == "999999")
                        {
                            endTime = "";
                        }
                        item.notes = string.Join(" - ", startTime, endTime);
                    }
                    item.modelNotes = string.Join("$$", item.description, item.otherDescription);
                    //clear nouse data
                    item.description = "";
                    item.otherDescription = "";
                    item.code = "";
                    item.startTime = null;
                    item.endTime = null;
                }
            }

            return res;
        }
        protected override void FilterPartsByVin(DbRESTFulRepository repository, ref List<Query_PartsResult> result, string vin, string selectorId)
        {
            if (!result.Any())
            {
                return;
            }
            var refSubGroupCodes = result.Where(q => string.IsNullOrEmpty(q.partCode) && q.imageSN != null && q.imageSN.Length == 4).Select(q => q.imageSN).Distinct();
            IEnumerable<Query_SubGroupResult> refSubGroups = new List<Query_SubGroupResult>();
            if (refSubGroupCodes != null && refSubGroupCodes.Any())
            {
                refSubGroups = repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_By_Code_For_Toyota, new { selectorId, subGroupCodes = refSubGroupCodes });
            }

            if (!string.IsNullOrEmpty(vin))
            {
                var vinInfo = GetVinInfo(repository, vin);
                if (vinInfo != null)
                {
                    string modelCode = vinInfo.modelCode;
                    string yearMonth = vinInfo.yearMonth;
                    int productionDate = yearMonth.ToInt();
                    string attr2 = vinInfo.attr2;

                    Get_SubGroup_filter_Param subgroupfilterParam = new Get_SubGroup_filter_Param()
                    {
                        modelCode = modelCode,
                        vinFilterCode = attr2
                    };
                    List<Query_VinFilterResult> vinFilterList = repository.Invoke<Query_VinFilterResult>(CSIs.Query_Vin_Filter_For_Toyota, subgroupfilterParam);

                    FilterSubGroupsByVinInfo(refSubGroups, productionDate, vinFilterList);
                    //所选subgroup是否benlongtovin
                    var imageSN = result.Select(q => q.subGroupCode).FirstOrDefault();
                    string subGroupCode = imageSN.Split('-')[0];
                    IEnumerable<Query_SubGroupResult> standardSubgroup = repository.Invoke<Query_SubGroupResult>(CSIs.Query_Standard_SubGroup_For_Toyota, new { selectorId, subGroupCodes = new string[] { subGroupCode } });

                    FilterSubGroupsByVinInfo(standardSubgroup, productionDate, vinFilterList);
                    var belongTos = standardSubgroup.Where(q => q.belongTo).Select(q => q.groupUniqueCode).Distinct();
                    //standardSubgroup = standardSubgroup.Where(q => q.isDisplay);
                    (from q in standardSubgroup join p in belongTos on q.groupUniqueCode equals p select q).ForEach(x => x.belongTo = true);

                    var subGroupIsOk = standardSubgroup.Where(q => q.imageSN.Equals(imageSN)).FirstOrDefault().belongTo;

                    List<Query_Vin_Country_Result> vinCounties = new List<Query_Vin_Country_Result>();

                    var partHasCountryCodeList = result.Where(e => !string.IsNullOrEmpty(e.countryCode));
                    if (!string.IsNullOrEmpty(vinInfo.optCode) && !string.IsNullOrEmpty(vinInfo.attr1) && partHasCountryCodeList != null && partHasCountryCodeList.Any())
                    {
                        vinCounties = repository.Invoke<Query_Vin_Country_Result>(CSIs.Query_Vin_Country_For_Toyota, new { versionCode = vinInfo.attr1, optCode = vinInfo.optCode });
                    }
                    foreach (var item in result)
                    {
                        if (!subGroupIsOk)
                        {
                            item.belongToVin = false;
                            continue;
                        }
                        if (!CheckPartInfo(item, productionDate, vinInfo, vinFilterList, vinCounties))
                        {
                            item.belongToVin = false;
                            continue;
                        }
                    }

                    //trimCodes特殊处理
                    foreach (var item in result.Where(e => e.belongToVin).GroupBy(e => e.imageSN))
                    {
                        //belongToVin为true的条数大于1时，做trimCodes过滤
                        if (item.Count() > 1)
                        {
                            foreach (var snItem in item)
                            {
                                //trimCodes
                                if (!string.IsNullOrEmpty(snItem.trimCodes) && !string.IsNullOrEmpty(vinInfo.trimColor))
                                {
                                    bool trimColorBelongTo = false;
                                    string vinTrimColor = vinInfo.trimColor;
                                    vinTrimColor = vinTrimColor.Substring(vinTrimColor.Length - 2);

                                    string partTrimcodes = snItem.trimCodes;
                                    while (!string.IsNullOrEmpty(partTrimcodes) && partTrimcodes.Length >= 2)
                                    {
                                        string tmpTrimCode = partTrimcodes.Substring(0, 2);
                                        bool charCheck = true;
                                        for (int i = 0; i < tmpTrimCode.Length; i++)
                                        {
                                            if (tmpTrimCode[i] != '#' && tmpTrimCode[i] != vinTrimColor[i])
                                            {
                                                charCheck = false;
                                                break;
                                            }
                                        }
                                        if (charCheck)
                                        {
                                            trimColorBelongTo = true;
                                            break;
                                        }
                                        partTrimcodes = partTrimcodes.Substring(2);
                                    }
                                    if (!trimColorBelongTo)
                                    {
                                        snItem.belongToVin = false;
                                        continue;

                                    }
                                }
                            }

                        }
                    }

                    //取优先级
                    foreach (var item in result.Where(e => e.belongToVin).GroupBy(e => e.imageSN))
                    {
                        //trimCodes
                        var trimCodeList = item.Where(e => !string.IsNullOrEmpty(e.trimCodes));
                        if (trimCodeList != null && trimCodeList.Any())
                        {
                            item.Where(e => string.IsNullOrEmpty(e.trimCodes))?.ForEach(e => e.belongToVin = false);
                            if (trimCodeList.Count() > 1)
                            {
                                var colorCodesList = trimCodeList.Where(e => !string.IsNullOrEmpty(e.colorCodes));
                                if (colorCodesList != null && colorCodesList.Any())
                                {
                                    trimCodeList.Where(e => string.IsNullOrEmpty(e.colorCodes))?.ForEach(e => e.belongToVin = false);

                                    if (colorCodesList.Count() > 1)
                                    {
                                        var countryCodeList = colorCodesList.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                        if (countryCodeList != null && countryCodeList.Any())
                                        {
                                            colorCodesList.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                        }
                                    }
                                }
                                else
                                {
                                    var countryCodeList = item.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                    if (countryCodeList != null && countryCodeList.Any())
                                    {
                                        item.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                    }
                                }
                            }
                        }
                        else
                        {
                            //colorCodes
                            var colorCodesList = item.Where(e => !string.IsNullOrEmpty(e.colorCodes));
                            if (colorCodesList != null && colorCodesList.Any())
                            {
                                item.Where(e => string.IsNullOrEmpty(e.colorCodes))?.ForEach(e => e.belongToVin = false);
                                if (colorCodesList.Count() > 1)
                                {
                                    var countryCodeList = colorCodesList.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                    if (countryCodeList != null && countryCodeList.Any())
                                    {
                                        colorCodesList.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                    }
                                }
                            }
                            else
                            {
                                //countryCode
                                var countryCodeList = item.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                if (countryCodeList != null && countryCodeList.Any())
                                {
                                    item.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                }
                            }
                        }
                    }
                }
            }

            foreach (var item in result)
            {
                if (string.IsNullOrEmpty(item.partCode) && item.imageSN != null)
                {
                    //跳转件
                    if (item.imageSN.Length == 4)
                    {
                        var refSubGroup = refSubGroups.Where(q => q.belongTo && q.code == item.imageSN).FirstOrDefault();
                        if (refSubGroup != null)
                        {
                            item.notes = $"参见: <a data='mainGroupId={refSubGroup.mainGroupId},subGroupId={refSubGroup.id}'>{item.imageSN}</a>";
                        }
                    }
                    //标准件
                    else
                    {
                        item.partName = "标准件";
                        item.partCode = item.imageSN;
                    }
                }
            }
        }

        private void FilterPartsByVin2(DbRESTFulRepository repository, ref List<PartCatalogResult> result, string vin, string selectorId)
        {
            if (!result.Any())
            {
                return;
            }
            if (!string.IsNullOrEmpty(vin))
            {
                Get_Model_InfoParam modelParam = new Get_Model_InfoParam();
                //获取vinPrefix
                if (vin.Length >= 8)
                {
                    modelParam.vinPrefix = vin.Substring(0, 8);
                }
                if (vin.Length >= 7)
                {
                    string backSevenVin = vin.Substring(vin.Length - 7);
                    //获取vinCode，后7位vin的前4位
                    modelParam.vinCode = backSevenVin.Substring(0, 4);

                    //获取vinSerialCode，后7位vin的后3位
                    modelParam.vinSerialCode = backSevenVin.Substring(4);
                }
                var vinInfo = repository.Invoke(CSIs.Query_Vin_By_Code_For_Toyota, modelParam);
                if (vinInfo != null)
                {
                    string modelCode = vinInfo.modelCode;
                    string yearMonth = vinInfo.yearMonth;
                    int productionDate = yearMonth.ToInt();
                    string attr2 = vinInfo.attr2;

                    Get_SubGroup_filter_Param subgroupfilterParam = new Get_SubGroup_filter_Param()
                    {
                        modelCode = modelCode,
                        vinFilterCode = attr2
                    };
                    List<Query_VinFilterResult> vinFilterList = repository.Invoke<Query_VinFilterResult>(CSIs.Query_Vin_Filter_For_Toyota, subgroupfilterParam);

                    //所选subgroup是否benlongtovin
                    var subGroupCodes = result.Select(q => q.subGroupCode.Split('-')[0]).Distinct();
                    IEnumerable<Query_SubGroupResult> standardSubgroup = repository.Invoke<Query_SubGroupResult>(CSIs.Query_Standard_SubGroup_For_Toyota, new { selectorId, subGroupCodes });

                    FilterSubGroupsByVinInfo(standardSubgroup, productionDate, vinFilterList);
                    var belongTos = standardSubgroup.Where(q => q.belongTo).Select(q => q.groupUniqueCode).Distinct();
                    //standardSubgroup = standardSubgroup.Where(q => q.isDisplay);
                    (from q in standardSubgroup join p in belongTos on q.groupUniqueCode equals p select q).ForEach(x => x.belongTo = true);

                    List<Query_Vin_Country_Result> vinCounties = new List<Query_Vin_Country_Result>();

                    var partHasCountryCodeList = result.Where(e => !string.IsNullOrEmpty(e.countryCode));
                    if (!string.IsNullOrEmpty(vinInfo.optCode) && !string.IsNullOrEmpty(vinInfo.attr1) && partHasCountryCodeList != null && partHasCountryCodeList.Any())
                    {
                        vinCounties = repository.Invoke<Query_Vin_Country_Result>(CSIs.Query_Vin_Country_For_Toyota, new { versionCode = vinInfo.attr1, optCode = vinInfo.optCode });
                    }
                    foreach (var item in result)
                    {
                        var subGroupIsOk = standardSubgroup.Any(q => q.imageSN.Equals(item.imageSN) && q.belongTo);
                        if (!subGroupIsOk)
                        {
                            item.belongToVin = false;
                            continue;
                        }

                        if (!CheckPartInfo(item, productionDate, vinInfo, vinFilterList, vinCounties))
                        {
                            item.belongToVin = false;
                            continue;
                        }
                    }

                    //trimCodes特殊处理
                    foreach (var item in result.Where(e => e.belongToVin).GroupBy(e => e.imageSN))
                    {
                        //belongToVin为true的条数大于1时，做trimCodes过滤
                        if (item.Count() > 1)
                        {
                            foreach (var snItem in item)
                            {
                                //trimCodes
                                if (!string.IsNullOrEmpty(snItem.trimCodes) && !string.IsNullOrEmpty(vinInfo.trimColor))
                                {
                                    bool trimColorBelongTo = false;
                                    string vinTrimColor = vinInfo.trimColor;
                                    vinTrimColor = vinTrimColor.Substring(vinTrimColor.Length - 2);

                                    string partTrimcodes = snItem.trimCodes;
                                    while (!string.IsNullOrEmpty(partTrimcodes) && partTrimcodes.Length >= 2)
                                    {
                                        string tmpTrimCode = partTrimcodes.Substring(0, 2);
                                        bool charCheck = true;
                                        for (int i = 0; i < tmpTrimCode.Length; i++)
                                        {
                                            if (tmpTrimCode[i] != '#' && tmpTrimCode[i] != vinTrimColor[i])
                                            {
                                                charCheck = false;
                                                break;
                                            }
                                        }
                                        if (charCheck)
                                        {
                                            trimColorBelongTo = true;
                                            break;
                                        }
                                        partTrimcodes = partTrimcodes.Substring(2);
                                    }
                                    if (!trimColorBelongTo)
                                    {
                                        snItem.belongToVin = false;
                                        continue;

                                    }
                                }
                            }

                        }
                    }

                    //取优先级
                    foreach (var item in result.Where(e => e.belongToVin).GroupBy(e => e.imageSN))
                    {
                        //trimCodes
                        var trimCodeList = item.Where(e => !string.IsNullOrEmpty(e.trimCodes));
                        if (trimCodeList != null && trimCodeList.Any())
                        {
                            item.Where(e => string.IsNullOrEmpty(e.trimCodes))?.ForEach(e => e.belongToVin = false);
                            if (trimCodeList.Count() > 1)
                            {
                                var colorCodesList = trimCodeList.Where(e => !string.IsNullOrEmpty(e.colorCodes));
                                if (colorCodesList != null && colorCodesList.Any())
                                {
                                    trimCodeList.Where(e => string.IsNullOrEmpty(e.colorCodes))?.ForEach(e => e.belongToVin = false);

                                    if (colorCodesList.Count() > 1)
                                    {
                                        var countryCodeList = colorCodesList.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                        if (countryCodeList != null && countryCodeList.Any())
                                        {
                                            colorCodesList.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                        }
                                    }
                                }
                                else
                                {
                                    var countryCodeList = item.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                    if (countryCodeList != null && countryCodeList.Any())
                                    {
                                        item.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                    }
                                }
                            }
                        }
                        else
                        {
                            //colorCodes
                            var colorCodesList = item.Where(e => !string.IsNullOrEmpty(e.colorCodes));
                            if (colorCodesList != null && colorCodesList.Any())
                            {
                                item.Where(e => string.IsNullOrEmpty(e.colorCodes))?.ForEach(e => e.belongToVin = false);
                                if (colorCodesList.Count() > 1)
                                {
                                    var countryCodeList = colorCodesList.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                    if (countryCodeList != null && countryCodeList.Any())
                                    {
                                        colorCodesList.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                    }
                                }
                            }
                            else
                            {
                                //countryCode
                                var countryCodeList = item.Where(e => !string.IsNullOrEmpty(e.countryCode));
                                if (countryCodeList != null && countryCodeList.Any())
                                {
                                    item.Where(e => string.IsNullOrEmpty(e.countryCode))?.ForEach(e => e.belongToVin = false);
                                }
                            }
                        }
                    }
                }
            }
        }

        bool CheckPartInfo(Query_PartsResult item, int productionDate, dynamic vinInfo, List<Query_VinFilterResult> vinFilterList, List<Query_Vin_Country_Result> vinCounties)
        {
            if (!DateOperator.CompareOriginalDate(item.startTime, item.endTime, productionDate, productionDate))
            {
                return false;
            }
            //versionCode
            if (!string.IsNullOrEmpty(item.versionCode) && !string.IsNullOrEmpty(vinInfo.attr1) && !item.versionCode.Equals(vinInfo.attr1))
            {
                return false;
            }
            //code1
            if (!string.IsNullOrEmpty(item.code1) && vinFilterList != null && vinFilterList.Any())
            {
                if (vinFilterList.FirstOrDefault(e => e.code == item.code1) == null)
                {
                    return false;
                }
            }

            //colorCodes
            if (!string.IsNullOrEmpty(item.colorCodes) && !string.IsNullOrEmpty(vinInfo.colorCode))
            {
                bool colorBelongTo = false;
                string vinColor = vinInfo.colorCode;

                string partColorcodes = item.colorCodes;
                while (!string.IsNullOrEmpty(partColorcodes) && partColorcodes.Length >= 3)
                {
                    string tmpColorCode = partColorcodes.Substring(0, 3);
                    if (tmpColorCode.Equals(vinColor))
                    {
                        colorBelongTo = true;
                        break;
                    }
                    partColorcodes = partColorcodes.Substring(3);
                }
                if (!colorBelongTo)
                {
                    return false;
                }
            }

            //country codes
            if (!string.IsNullOrEmpty(item.countryCode) && vinCounties.Any())
            {
                if (vinCounties.FirstOrDefault(e => e.code2 == item.countryCode) == null)
                {
                    return false;
                }
            }
            return true;
        }

        protected override List<Query_SubGroupResult> BuildSubGroupResults(List<Query_SubGroupResult> result)
        {
            return result;
        }

        protected override IEnumerable<dynamic> GetHotPoints(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke(CSIs.Query_HotPoints_For_Toyota, param);
        }

        public override object QueryModel(DbRESTFulRepository repository, JObject param)
        {
            Get_Model_InfoParam modelParam = param.ToObject<Get_Model_InfoParam>();
            Get_Model_InfoResult result = new Get_Model_InfoResult();
            string vin = modelParam.vin;
            if (!string.IsNullOrEmpty(vin))
            {
                var vinInfo = GetVinInfo(repository, vin);
                if (vinInfo == null)
                {
                    throw new LogicalException($"未找到该vin码(toyota):{vin}。", 610);
                }
                string modelCode = vinInfo.modelCode;
                string yearMonth = vinInfo.yearMonth;
                result = JObject.FromObject(vinInfo).ToObject<Get_Model_InfoResult>();

                result.props = new List<Get_Model_InfoResult._props>();
                result.props.Add(new Get_Model_InfoResult._props { key = "车型", value = vinInfo.NAME });
                result.props.Add(new Get_Model_InfoResult._props { key = "车型代码", value = vinInfo.vehicleCode });
                result.props.Add(new Get_Model_InfoResult._props { key = "生产日期", value = yearMonth });
                result.props.Add(new Get_Model_InfoResult._props { key = "车身颜色", value = vinInfo.colorCode });
                result.props.Add(new Get_Model_InfoResult._props { key = "内饰颜色", value = vinInfo.trimColor });
                result.props.Add(new Get_Model_InfoResult._props { key = "发动机", value = vinInfo.attr3 });
                result.props.Add(new Get_Model_InfoResult._props { key = "发动机2", value = vinInfo.attr4 });
                result.props.Add(new Get_Model_InfoResult._props { key = "车身", value = vinInfo.attr7 });
                result.props.Add(new Get_Model_InfoResult._props { key = "等级", value = vinInfo.attr8 });
                result.props.Add(new Get_Model_InfoResult._props { key = "ATM/MTM", value = vinInfo.attr9 });
                result.props.Add(new Get_Model_InfoResult._props { key = "变速器", value = vinInfo.attr10 });
                result.props.Add(new Get_Model_InfoResult._props { key = "车架号", value = vin });
                result.props = result.props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();

                result.features = new List<Get_Model_InfoResult._features>();

                var features = Resources.ResourceHelper.ToyotaFeatureDict[modelCode];
                List<Family_Toyota> familys = repository.Invoke<Family_Toyota>(CSIs.Query_Family_For_Toyota, new { modelCode });
                features = FilterFeaturesByCombine(features, vinInfo, familys);
                foreach (var feature in features)
                {
                    result.features.Add(new Get_Model_InfoResult._features { key = feature.familyName, value = feature.attr + "(" + feature.name + ")" });
                }
            }
            else
            {
                var ids = modelParam.id.Split("_");
                if (ids.Count() > 1)
                {
                    modelParam.id = ids[1];
                }
                var model = repository.Invoke(CSIs.Get_Model, modelParam);
                if (model != null)
                {
                    result = JObject.FromObject(model).ToObject<Get_Model_InfoResult>();
                    result.props = GetModelProps(repository, param);
                }
            }
            return result;
        }

        private List<Feature_Toyota> FilterFeaturesByCombine(List<Feature_Toyota> features, dynamic combine, List<Family_Toyota> familys)
        {
            List<Feature_Toyota> retList = new List<Feature_Toyota>();
            var dic = ((IDictionary<string, object>)combine);

            foreach (var family in familys)
            {
                var intSn = family.sn.ToInt();
                int intAttr;
                if (intSn == 1)
                {
                    intAttr = 3;
                }
                else
                {
                    intAttr = intSn + 4;
                }

                string param = "attr" + intAttr;
                var attr = dic[param];
                if (attr != null)
                {
                    var f = features.Where(q => q.attr == attr.ToString() && q.sn == family.sn).FirstOrDefault();
                    if (f != null)
                    {
                        f.familyName = family.name;
                        retList.Add(f);
                    }
                }
            }
            return retList;
        }

        protected override List<Query_SubGroupResult> FilterSubGroupsByVin(DbRESTFulRepository repository, List<Query_SubGroupResult> results, JObject param)
        {
            var vin = param.Value<string>(ParamFields._vin);
            if (results == null || results.Count == 0)
            {
                return results;
            }
            if (!string.IsNullOrEmpty(vin))
            {
                var vinInfo = GetVinInfo(repository, vin);
                if (vinInfo != null)
                {
                    string modelCode = vinInfo.modelCode;
                    string yearMonth = vinInfo.yearMonth;
                    int productionDate = yearMonth.ToInt();
                    string attr2 = vinInfo.attr2;

                    Get_SubGroup_filter_Param subgroupfilterParam = new Get_SubGroup_filter_Param()
                    {
                        modelCode = modelCode,
                        vinFilterCode = attr2
                    };
                    List<Query_VinFilterResult> vinFilterList = repository.Invoke<Query_VinFilterResult>(CSIs.Query_Vin_Filter_For_Toyota, subgroupfilterParam);

                    FilterSubGroupsByVinInfo(results, productionDate, vinFilterList);
                }
                var belongTos = results.Where(q => q.belongTo).Select(q => q.groupUniqueCode).Distinct();
                //results = results.Where(q => q.isDisplay).ToList();
                (from q in results join p in belongTos on q.groupUniqueCode equals p select q).ForEach(x => x.belongTo = true);
            }
            else
            {
                results = results.Where(q => q.isDisplay).ToList();
            }
            return results;
        }

        private void FilterSubGroupsByVinInfo(IEnumerable<Query_SubGroupResult> results, int productionDate, List<Query_VinFilterResult> codeFilterList)
        {
            if (!results.Any())
            {
                return;
            }
            foreach (var item in results)
            {
                if (!DateOperator.CompareOriginalDate(item.startTime, item.endTime, productionDate, productionDate))
                {
                    item.belongTo = false;
                    continue;
                }
                //sub_group_filter
                if (codeFilterList.FirstOrDefault(e => e.code == item.subgroupFilterCode) == null)
                {
                    item.belongTo = false;
                    continue;
                }
            }
        }

        public override object QueryPartDetail(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            var brandCode = param.Value<string>(ParamFields._brandCode);
            var partId = param.Value<string>(ParamFields._partId);
            var partCode = param.Value<string>(ParamFields._partCode);
            dynamic data = null;

            if (string.IsNullOrEmpty(partId))
            {
                data = repository.Invoke(CSIs.Get_Part_Detail_For_Toyota, new { partCode = partCode, brandCode });
            }
            else
            {
                data = repository.Invoke(CSIs.Get_Usage_Detail_For_Toyota, param);
            }
            if (data == null) return null;
            // 1、基本信息赋值
            Query_Part_DetailResult result = JObject.FromObject(data).ToObject<Query_Part_DetailResult>();

            // 2、价格
            if (!string.IsNullOrEmpty(partId))
            {
                IEnumerable<Part_Price> partAttrs = repository.Invoke<Part_Price>(CSIs.Get_Part_Price, new { result.partCode });
                partAttrs = partAttrs.Where(q => !q.marketCode.Equals(result.marketCode));
                if (partAttrs.Any())
                {
                    result.partAttributes = partAttrs.Select(q => new Query_Part_DetailResult._partAttribute
                    {
                        partCode = q.partCode,
                        marketCode = q.marketCode,
                        marketName = q.marketName,
                        brandCode = q.brandCode,
                        brandName = BrandDictionary.GetName(q.brandCode),
                        cost = q.cost,
                        price = q.price,
                        priceUpdatedAt = q.priceUpdatedAt,
                        priceFC = q.priceFC,
                        stock = q.stock,
                        props = new List<Query_Part_DetailResult._prop> { new Query_Part_DetailResult._prop { key = "厂商", value = q.marketName } }
                    }).ToList();
                }
            }

            result.replacements = new List<Query_Part_DetailResult._replacement>();
            //3.替换件处理
            if (!string.IsNullOrEmpty(data.supersession))
            {
                List<Query_Part_DetailResult._replacement> replacements = repository.Invoke<Query_Part_DetailResult._replacement>(CSIs.Query_Parts_By_Codes, new { partCodes = data.supersession.Split(',') });
                if (replacements != null && replacements.Any())
                {
                    foreach (var replaceItem in replacements)
                    {
                        replaceItem.brandName = BrandDictionary.GetName(replaceItem.brandCode);
                        replaceItem.props = new List<Query_Part_DetailResult._prop>();
                        if (!string.IsNullOrEmpty(data.supersessionType))
                        {
                            replaceItem.props.Add(new Query_Part_DetailResult._prop { key = "替换类型", value = data.supersessionType });
                        }

                        if (!string.IsNullOrEmpty(replaceItem.marketName))
                        {
                            replaceItem.props.Add(new Query_Part_DetailResult._prop { key = "厂商", value = replaceItem.marketName });
                        }
                        result.replacements.Add(replaceItem);
                    }
                }
            }
            //4.配件附加属性处理
            var props = new List<Query_Part_DetailResult._prop>
            {
                new Query_Part_DetailResult._prop { key = "件数", value = result.quantity ?? string.Empty },
                new Query_Part_DetailResult._prop { key = "生效日期", value = data.startTime?.ToString() ?? string.Empty },
                new Query_Part_DetailResult._prop { key = "有效日期", value = data.endTime?.ToString() ?? string.Empty},
                new Query_Part_DetailResult._prop { key = "Specification", value = data.specification?? string.Empty},
                new Query_Part_DetailResult._prop { key = "Spec Code", value = data.specCode?? string.Empty},
                new Query_Part_DetailResult._prop { key = "Trim Color", value = data.trimColor?? string.Empty},
                new Query_Part_DetailResult._prop { key = "Body Color", value = data.bodyColor?? string.Empty},
                new Query_Part_DetailResult._prop { key = "Country", value = data.country?? string.Empty},
            };
            result.props = props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();
            return result;
        }

        protected override dynamic GetModelsByPart(DbRESTFulRepository repository, int pageIndex, int pageSize, string brandCode, string partCode)
        {
            return repository.Invoke(CSIs.Query_Models_By_Part_For_Toyota, new { pageIndex, pageSize, brandCode, partCode = partCode });
        }

        protected override dynamic GetHotPointsByPart(DbRESTFulRepository repository, string brandCode, string partCode, IEnumerable<string> imageIds)
        {
            return repository.Invoke(CSIs.Query_HotPoints_By_Part_For_Toyota, new { brandCode, partCode = partCode, imageIds });
        }
        protected override List<SearchSubGroupResults> GetSearchResults(DbRESTFulRepository repository, string brandCode, string[] partCodes, string selectorId)
        {
            return repository.Invoke<SearchSubGroupResults>(CSIs.Search_SubGroups_By_PartCodes_For_Toyota, new { brandCode, partCodes, selectorId });
        }

        public override object SearchParts(DbRESTFulRepository repository, JObject param)
        {
            param.RemoveEmptyValues();
            var brandCode = param.Value<string>(ParamFields._brandCode);
            var selectorId = param.Value<string>(ParamFields._selectorId);
            var partCodes = param.Value<string>("partCodes");
            var vin = param.Value<string>(ParamFields._vin);
            List<SearchSubGroupResults> searchResults = GetSearchResults(repository, brandCode, partCodes.Split(','), selectorId);
            List<Query_MainGroupResult> mainGroups = searchResults.Select(q => new { q.mainGroupCode, q.mainGroupName }).Distinct().Select(x => new Query_MainGroupResult { id = x.mainGroupCode, code = x.mainGroupCode, name = x.mainGroupName, isBelongTo = true }).ToList();
            List<Query_SubGroupResult> subGroups = searchResults.Select(x => new Query_SubGroupResult { code = x.subGroupCode, belongTo = true, imageSN = x.imageSN, imageUrl = x.imageUrl, mainGroupId = x.mainGroupCode, mainGroupCode = x.mainGroupCode, name = x.subGroupName, id = x.subGroupId, applicableModel = x.applicableModel, remark = x.remark, startTime = x.startTime, endTime = x.endTime, isDisplay = x.isDisplay, groupUniqueCode = x.groupUniqueCode, imageCode = x.imageCode, subgroupFilterCode = x.subgroupFilterCode }).ToList();
            subGroups = FilterSubGroupsByVin(repository, subGroups, param);
            subGroups = BuildSubGroupResults(subGroups);
            return new SearchPartsResult { mainGroups = mainGroups, subGroups = subGroups };
        }

        protected override List<QuickPartResult> QuickQueryParts(DbRESTFulRepository repository, IEnumerable<string> partCodes, string brandCode)
        {
            return repository.Invoke<QuickPartResult>(CSIs.Query_QuickParts_For_Toyota, new { partCodes = partCodes, brandCode }); ;
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByMarket(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId)
        {
            List<QuickPartResult> ret = new List<QuickPartResult>();
            if (parts != null && parts.Any())
            {
                string marketCode = string.Empty;
                var modelInfo = repository.Invoke(CSIs.Get_MarketCode_By_SelectorId, new { selectorId });
                if (modelInfo != null)
                {
                    marketCode = modelInfo.marketCode;
                }
                foreach (var item in parts)
                {
                    if (item.marketCode == marketCode)
                    {
                        ret.Add(item);
                    }
                }
            }
            return ret;
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByUsage_Vin(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId, string vin)
        {
            List<QuickPartResult> ret = new List<QuickPartResult>();
            if (!string.IsNullOrEmpty(vin) && parts != null && parts.Any())
            {
                string vinPrefix = string.Empty, vinCode = string.Empty, vinSerialCode = string.Empty;
                if (vin.Length >= 8)
                {
                    vinPrefix = vin.Substring(0, 8);
                }
                if (vin.Length >= 7)
                {
                    string backSevenVin = vin.Substring(vin.Length - 7);
                    //获取vinCode，后7位vin的前4位
                    vinCode = backSevenVin.Substring(0, 4);

                    //获取vinSerialCode，后7位vin的后3位
                    vinSerialCode = backSevenVin.Substring(4);
                }
                List<string> partCodes = parts.Select(e => e.partCode).Distinct().ToList();
                List<Query_PartsResult> partUsages = repository.Invoke<Query_PartsResult>(CSIs.Quick_PartUsage_For_Toyota, new { selectorId, partCodes });
                if (partUsages != null && partUsages.Any())
                {
                    List<string> usedPartCodes = new List<string>();

                    Get_Model_InfoParam modelParam = new Get_Model_InfoParam() { vinPrefix = vinPrefix, vinCode = vinCode, vinSerialCode = vinSerialCode };

                    var vinInfo = repository.Invoke(CSIs.Query_Quick_Vin_For_Toyota, modelParam);
                    if (vinInfo != null)
                    {
                        IEnumerable<int> subgroupIds = partUsages.Where(e => e.subgroupId != null && e.subgroupId > 0).Select(e => (int)e.subgroupId);
                        List<Query_SubGroupResult> subgroupList = repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_By_Ids_For_Toyota, new { subgroupIds = subgroupIds });

                        string modelCode = vinInfo.modelCode;
                        string yearMonth = vinInfo.yearMonth;
                        int productionDate = yearMonth.ToInt();
                        string attr2 = vinInfo.attr2;

                        Get_SubGroup_filter_Param subgroupfilterParam = new Get_SubGroup_filter_Param()
                        {
                            modelCode = modelCode,
                            vinFilterCode = attr2
                        };
                        List<Query_VinFilterResult> vinFilterList = repository.Invoke<Query_VinFilterResult>(CSIs.Query_Vin_Filter_For_Toyota, subgroupfilterParam);

                        FilterSubGroupsByVinInfo(subgroupList, productionDate, vinFilterList);

                        List<Query_Vin_Country_Result> vinCounties = new List<Query_Vin_Country_Result>();
                        var partHasCountryCodeList = partUsages.Where(e => !string.IsNullOrEmpty(e.countryCode));
                        if (!string.IsNullOrEmpty(vinInfo.optCode) && !string.IsNullOrEmpty(vinInfo.attr1) && partHasCountryCodeList != null && partHasCountryCodeList.Any())
                        {
                            vinCounties = repository.Invoke<Query_Vin_Country_Result>(CSIs.Query_Vin_Country_For_Toyota, new { versionCode = vinInfo.attr1, optCode = vinInfo.optCode });
                        }
                        foreach (var item in partUsages)
                        {
                            if (string.IsNullOrEmpty(item.partCode) && !string.IsNullOrEmpty(item.imageSN))
                            {
                                //跳转件
                                if (item.imageSN.Length == 4)
                                {
                                    continue;
                                }
                                //标准件
                                else
                                {
                                    item.partName = "标准件";
                                    item.partCode = item.imageSN;
                                }
                            }
                            if (item.subgroupId != null && item.subgroupId > 0)
                            {
                                var subgroup = subgroupList.FirstOrDefault(e => e.id == item.subgroupId.ToString());
                                if (subgroup != null)
                                {
                                    //sub_group不属于vin
                                    if (!subgroup.belongTo)
                                    {
                                        continue;
                                    }
                                }
                            }

                            if (!CheckPartInfo(item, productionDate, vinInfo, vinFilterList, vinCounties))
                            {
                                continue;
                            }

                            usedPartCodes.Add(item.partCode);
                        }

                        if (usedPartCodes.Any())
                        {
                            ret = parts.Where(e => usedPartCodes.Contains(e.partCode)).ToList();
                        }
                    }
                }
            }
            return ret;
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByUsage_Model(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId)
        {
            List<QuickPartResult> ret = new List<QuickPartResult>();
            if (selectorId > 0 && parts != null && parts.Any())
            {
                List<string> partCodes = parts.Select(e => e.partCode).Distinct().ToList();

                List<Query_PartsResult> partUsages = repository.Invoke<Query_PartsResult>(CSIs.Quick_PartUsage_By_SelectorId_For_Toyota, new { selectorId, partCodes });
                if (partUsages != null && partUsages.Any())
                {
                    foreach (var item in parts)
                    {
                        if (partUsages.FirstOrDefault(e => e.partCode == item.partCode) != null || partUsages.FirstOrDefault(e => string.IsNullOrEmpty(e.partCode) && e.imageSN.Length != 4 && e.imageSN == item.partCode) != null)
                        {
                            ret.Add(item);
                        }
                    }
                }
            }
            return ret;
        }

        protected override List<PartCatalog> GetPartCatalogs(DbRESTFulRepository repository, IEnumerable<string> partCodes, string selectorId, string brandCode, string vinCode)
        {
            List<PartCatalogResult> partCatalogResults = repository.Invoke<PartCatalogResult>(CSIs.Query_Part_Catalog_For_Toyota, new { selectorId, partCodes });
            partCatalogResults = GroupParts2(partCatalogResults);
            FilterPartsByVin2(repository, ref partCatalogResults, vinCode, selectorId);
            partCatalogResults = partCatalogResults.Where(q => q.belongToVin).ToList();
            var hotPointsModel = repository.Invoke(CSIs.Query_HotPoints_By_Parts_For_Toyota, new { brandCode, subGroupIds = partCatalogResults.Select(q => q.subGroupId).Distinct(), partCodes = partCatalogResults.Select(q => q.partCode).Distinct() });
            JArray allPoints = JArray.FromObject(hotPointsModel);

            foreach (var item in partCatalogResults)
            {
                //2.1适用车型多张图片处理
                var imgs = allPoints.Where(p => p.Value<int>("subGroupId") == item.subGroupId).Select(p => p.Value<string>("url")).Distinct().Select(x => new _imgs { url = x }).ToList();
                foreach (var img in imgs)
                {
                    //2.1.1适用车型每张图片对应的热点处理
                    img.points = allPoints.Where(p => p.Value<string>("url") == img.url && p.Value<string>("sn") == item.sn)
                                       .Select(p => p.ToObject<_imgs._points>()).ToList();
                }
                item.imgs = imgs;
            }
            return BuildPartCatalogList(partCatalogResults);
        }

        private dynamic GetVinInfo(DbRESTFulRepository repository, string vin)
        {
            Get_Model_InfoParam modelParam = new Get_Model_InfoParam() { vin = vin };

            //获取vinPrefix
            if (vin.Length >= 8)
            {
                modelParam.vinPrefix = vin.Substring(0, 8);
            }
            string backSevenVin = string.Empty;
            if (vin.Length >= 7)
            {
                backSevenVin = vin.Substring(vin.Length - 7);
                //获取vinCode，后7位vin的前4位
                modelParam.vinCode = backSevenVin.Substring(0, 4);

                //获取vinSerialCode，后7位vin的后3位
                modelParam.vinSerialCode = backSevenVin.Substring(4);
            }

            var vinInfo = repository.Invoke(CSIs.Query_Vin_By_Code_For_Toyota, modelParam);
            if (vinInfo != null)
            {
                string yearMonth = vinInfo.yearMonth;
                string startYearMonth = vinInfo.startYearMonth;
                string endYearMonth = vinInfo.endYearMonth;
                int productionDate = yearMonth.ToInt();
                int startDate = startYearMonth.ToInt();
                int endDate = endYearMonth.ToInt();
                if (productionDate < startDate || productionDate > endDate)
                {
                    string vinYearCode = vin[9].ToString().ToUpper();
                    if (!_vinYearDic.ContainsKey(vinYearCode))
                    {
                        return null;
                    }
                    string vinYear = _vinYearDic[vinYearCode];
                    string seriesCode = vinInfo.seriesCode;

                    string vinFramnoMonth = repository.Invoke<string>(CSIs.Get_Vin_Framno_For_Toyota, new { seriesCode = seriesCode, year = vinYear });
                    if (string.IsNullOrEmpty(vinFramnoMonth))
                    {
                        return null;
                    }
                    int compare = CompareCodes(backSevenVin, vinFramnoMonth);
                    if (compare < 0)
                    {
                        return null;
                    }
                }
            }

            return vinInfo;
        }

        private int CompareCodes(string vinCode, string framnoCode)
        {
            for (int i = 0; i < vinCode.Length; i++)
            {
                var a = vinCode[i];
                var b = framnoCode[i];
                if (a > b)
                {
                    return 1;
                }
                else if (a < b)
                {
                    return -1;
                }
            }
            return 0;
        }

        //丰田数据源是2000之后
        Dictionary<string, string> _vinYearDic = new Dictionary<string, string>
        {
            { "1","2001" },
            { "2","2002" },
            { "3","2003" },
            { "4","2004" },
            { "5","2005" },
            { "6","2006" },
            { "7","2007" },
            { "8","2008" },
            { "9","2009" },
            { "A","2010" },
            { "B","2011" },
            { "C","2012" },
            { "D","2013" },
            { "E","2014" },
            { "F","2015" },
            { "G","2016" },
            { "H","2017" },
            { "J","2018" },
            { "K","2019" },
            { "L","2020" },
            { "M","2021" },
            { "N","2022" },
            { "P","2023" },
            { "R","2024" },
            { "S","2025" },
            { "T","2026" },
            { "V","2027" },
            { "W","2028" },
            { "X","2029" },
            { "Y","2030" },
        };
    }
}



